#include "lea.h"

Lea::Lea(Sentencia *next, vector<string> variable, Variable *var, int fila, int col):Sentencia(next,fila,col)
{
    this->variable = variable;
    this->var = var;
}

string Lea::is()
{
    return "LEA";
}

void Lea::setvariable(vector<string> variable)
{
    this->variable=variable;
}

void Lea::setVar(Variable *var)
{
    this->var=var;
}

Variable *Lea::getVar()
{
    return this->var;
}

vector<string> Lea::getvariable()
{
    return this->variable;
}

Tipo_ts *Lea::validarSemantica(Tabla_Simbolos *tabla_de_tipo, Tabla_Simbolos *tabla_de_varaible)
{Tipo_ts *tts;

    for(int i=0;i<this->getvariable().size();i++){
        tts = tabla_de_varaible->get(this->getvariable().at(i))->getTipo();
        if(tts!=0){
        if(tts->is().compare("PIN")!=0){
            stringstream out;
            out << "Variable No es de Tipo PIN " <<this->getvariable().at(i) <<" Columna: "<<this->getCol()<< " Fila: "<<this->getFila();
            throw  exception(out.str().c_str());
        }else{
            Pin *p = (Pin*)tts;
            if(p->getModo()==0){
                stringstream out;
                out << "PIN tiene que ser de entrada" <<this->getvariable().at(i) <<" Columna: "<<this->getCol()<< " Fila: "<<this->getFila();
                throw  exception(out.str().c_str());
            }
        }
        }else{
            stringstream out;
            out << "Variable No Existe " <<this->getvariable().at(i) <<" Columna: "<<this->getCol()<< " Fila: "<<this->getFila();
            throw  exception(out.str().c_str());
        }
    }
    Tipo_ts *variable_ = tabla_de_varaible->get(this->var->getValor())->getTipo();

    if(variable_->is().compare("ENTERO")==0){
        PinVariable *pv = (PinVariable*)this->var;

        pv->validarSemantica(tabla_de_tipo,tabla_de_varaible);


    }else{
        stringstream out;
        out << "Se esperaba variable de tipo Entero "<<" Columna: "<<this->getCol()<< " Fila: "<<this->getFila();
        throw  exception(out.str().c_str());
    }

    if(this->getNext()!=0){
        this->getNext()->SetReturn(this->GetReturn());
        this->getNext()->validarSemantica(tabla_de_tipo,tabla_de_varaible);
    }
    return 0;
}

string Lea::generarCodigo(GenerarVariable *var, Tabla_Simbolos *tabla_de_tipo, Tabla_Simbolos *tabla_de_varaible)
{
    string codigo;
    string inicio = var->getNewVariable("inicio");
    string final = var->getNewVariable("final");
    string temp = var->getNewVariable("temp");
    PinVariable *pv = (PinVariable*)this->var;

    codigo = "\nint "+ inicio+" = "+pv->getInicio()->generarCodigo(var,tabla_de_tipo,tabla_de_varaible).codigo+";\n";
    codigo += "int "+final+" = "+pv->getFin()->generarCodigo(var,tabla_de_tipo,tabla_de_varaible).codigo+";\n";
    codigo += "int "+temp+" = "+ inicio+";\n";
    for(int i=0;i<this->variable.size();i++){
        codigo += "if("+inicio+" < "+final+"){\n";
        codigo += "if(";
        Pin *pin_ =(Pin*)tabla_de_varaible->get(this->variable.at(i))->getTipo();

        this->it3 = this->pinleer.find(pin_->getPin());
        this->it = this->pindir.find(pin_->getPin());
        codigo += this->it3->second +"& 1 << ";
        QString n_;
        n_.setNum(this->it->second,10);
        codigo += n_.toStdString()+"){\n";
        codigo +="_"+this->var->getValor()+"_ |= 1 << "+temp +";\n}else{\n";
        codigo +="_"+this->var->getValor()+"_ &= ~ (1 << "+temp+");\n}\n";
        codigo += temp+"++;";
        codigo += "\n}else{\n";
        codigo += "if(";
        Pin *pin =(Pin*)tabla_de_varaible->get(this->variable.at(i))->getTipo();

        this->it3 = this->pinleer.find(pin->getPin());
        this->it = this->pindir.find(pin->getPin());
        codigo += this->it3->second +"& 1 << ";
        QString n;
        n.setNum(this->it->second,10);
        codigo += n.toStdString()+"){\n";
        codigo +="_"+this->var->getValor()+"_ |= 1 << "+temp +";\n}else{\n";
        codigo +="_"+this->var->getValor()+"_ &= ~ (1 << "+temp+");\n}\n";
        codigo += temp+"--;";
        codigo +="\n}\n\n";

    }

    if(this->getNext()!=0){
        codigo += this->getNext()->generarCodigo(var,tabla_de_tipo,tabla_de_varaible);
    }

    return codigo;

}
